package cn.yj.config.web;

import cn.yj.commons.StringPools;
import cn.yj.commons.utils.ServletUtils;
import cn.yj.commons.utils.StringUtils;
import cn.yj.config.annotation.Anonymous;
import cn.yj.entity.R;
import cn.yj.syslog.entity.SysLog;
import com.alibaba.fastjson.JSON;
import org.apache.shiro.util.AntPathMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @author 永健
 * @since 2021-04-29 15:48
 */
public abstract class AbstractInterceptor implements HandlerInterceptor {
    private Logger log = LoggerFactory.getLogger(getClass());

    protected <T> T getAnnotation(Object handlerMethod, Class<Anonymous> annotation) {
        if (handlerMethod instanceof HandlerMethod) {
            return (T) ((HandlerMethod) handlerMethod).getMethodAnnotation(annotation);
        }
        return null;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        request.setAttribute("device", SysLog.APP);
        request.setAttribute("user", "");
        return doPreHandle(request, response, handler);
    }

    protected abstract boolean doPreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    protected boolean exitsAnnotation(Object handlerMethod, Class<Anonymous> annotation) {
        return getAnnotation(handlerMethod, annotation) != null;
    }

    protected boolean setHttpResponse(R r, HttpServletResponse response) throws IOException {
        PrintWriter out = null;
        try {
            //设置编码
            response.setCharacterEncoding("UTF-8");
            //设置返回类型
            response.setContentType("application/json");
            out = response.getWriter();
            //输出
            response.getWriter().write(JSON.toJSONString(r));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            out.flush();
            out.close();
        }
        log.warn("未登陆拦截,URL={}", ServletUtils.getRequest().getRequestURI());
        return false;
    }


    private AntPathMatcher matcher = new AntPathMatcher();

    @Value("${permissions.exclude-url}")
    private List<String> excludeUrl;

    @Value("${server.servlet.context-path:''}")
    private String serverContext;

    protected boolean matches(String source) {
        final String sourceUrl = source.replace(serverContext, StringPools.EMPTY);
        boolean flag = false;
        if (!StringUtils.isNull(excludeUrl) && !excludeUrl.isEmpty()) {
            for (String patten : excludeUrl) {
                if (matcher.matches(patten, sourceUrl)) {
                    flag = true;
                    break;
                    //throw new ServiceException("该请求需要验证");
                }
            }
        }
        return flag;
    }
}
